package com.qen.service;

import com.qen.common.BeetlUtils;
import com.qen.common.GenericTypeUtils;
import com.qen.repository.BaseDao;
import com.qen.wrapper.Wrapper;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.page.PageRequest;
import org.beetl.sql.core.page.PageResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * @author licz
 * @data 2025年05月22日 4:34 PM
 */
public abstract class AbstractService<T, M extends BaseDao<T>> implements IService<T> {

    protected final Logger log = LoggerFactory.getLogger(getClass());

    private Class<T> entityClass;

    private Class<M> daoClass;

    private volatile SQLManager sqlManager;

    protected SQLManager getSqlManager() {
        if (this.sqlManager == null) {
            sqlManager = BeetlUtils.getSQLManager();
        }
        return this.sqlManager;
    }

    public Class<M> getDaoClass() {
        if (this.daoClass == null) {
            this.daoClass = GenericTypeUtils.getGenericType(getClass().getGenericSuperclass(), 1);
        }
        return this.daoClass;
    }

    @Override
    public Class<T> getEntityClass() {
        if (this.entityClass == null) {
            this.entityClass = GenericTypeUtils.getGenericType(getClass().getGenericSuperclass());
        }
        return this.entityClass;
    }

    @Override
    public <E> E findObjectByKey(Serializable key, Class<E> clz) {
        return getBaseDao().findObjectByKey(key, clz);
    }

    @Override
    public <E> List<E> findObjectByKey(List<? extends Serializable> keys, Class<E> clz) {
        return getBaseDao().findObjectByKey(keys, clz);
    }

    @Override
    public <E> E querySingleObject(String sql, Object params, Class<E> clz, boolean strictMode) {
        return getBaseDao().querySingleObject(sql, params, clz, strictMode);
    }

    @Override
    public <E> PageResult<E> queryEntityListPageable(String sql, Map<String, Object> params, int pageNum, int pageSize, boolean isTotalRequired, Class<E> clz) {
        return getBaseDao().queryEntityListPageable(sql, params, pageNum, pageSize, isTotalRequired, clz);
    }

    @Override
    public <E> List<E> queryEntityList(String sql, Object params, Class<E> clz) {
        return getBaseDao().queryEntityList(sql, params, clz);
    }

    @Override
    public <E> E querySingleObjectFromMarkdown(String fileName, String sqlMark, Map<String, Object> params, Class<E> clz) {
        return getBaseDao().querySingleObjectFromMarkdown(fileName, sqlMark, params, clz);
    }

    @Override
    public <E> List<E> queryEntityListFromMarkDown(String fileName, String sqlMark, Map<String, Object> params, Class<E> clz) {
        return getBaseDao().queryEntityListFromMarkDown(fileName, sqlMark, params, clz);
    }

    @Override
    public T selectOne(Wrapper<T> queryWrapper, boolean throwEx) {
        return getBaseDao().selectOne(queryWrapper, throwEx);
    }

    @Override
    public <E> Long selectCount(Wrapper<T> queryWrapper, Class<E> clz) {
        return getBaseDao().selectCount(queryWrapper, clz);
    }

    @Override
    public <E, P extends PageRequest<E>> PageResult<E> selectList(P page, Wrapper<T> queryWrapper, Class<E> clz) {
        return getBaseDao().selectList(page, queryWrapper, clz);
    }

    @Override
    public List<Map<String, Object>> queryMapList(String sql, Map<String, Object> params) {
        return getBaseDao().queryMapList(sql, params);
    }

    @Override
    public PageResult<Map<String, Object>> queryMapListPageable(String sql, Map<String, Object> params, int pageNum, int pageSize, boolean isTotalRequired) {
        return getBaseDao().queryMapListPageable(sql, params, pageNum, pageSize, isTotalRequired);
    }

    @Override
    public List<Map<String, Object>> queryMapListFromMarkDown(String fileName, String sqlMark, Map<String, Object> params) {
        return getBaseDao().queryMapListFromMarkDown(fileName, sqlMark, params);
    }

    @Override
    public List<Map<String, Object>> selectMaps(Wrapper<T> queryWrapper) {
        return getBaseDao().selectMaps(queryWrapper);
    }

    @Override
    public <P extends PageRequest<Map>> List<Map<String, Object>> selectMaps(P page, Wrapper<T> queryWrapper) {
        return getBaseDao().selectMaps(page, queryWrapper);
    }

    @Override
    public T findObjectByKey(Serializable key) {
        return getBaseDao().findObjectByKey(key);
    }

    @Override
    public List<T> findObjectByKey(List<? extends Serializable> idList) {
        return getBaseDao().findObjectByKey(idList);
    }

    @Override
    public PageResult<T> queryEntityListPageable(String sql, Map<String, Object> params, int pageNum, int pageSize, boolean isTotalRequired) {
        return getBaseDao().queryEntityListPageable(sql, params, pageNum, pageSize, isTotalRequired);
    }

    @Override
    public List<T> queryEntityList(String sql, Map<String, Object> params) {
        return getBaseDao().queryEntityList(sql, params);
    }

    @Override
    public List<T> queryEntityList(String sql, Object params) {
        return getBaseDao().queryEntityList(sql, params);
    }

    @Override
    public List<T> queryEntityListFromMarkdown(String fileName, String sqlMark, Map<String, Object> params) {
        return getBaseDao().queryEntityListFromMarkdown(fileName, sqlMark, params);
    }

    @Override
    public Long selectCount(Wrapper<T> queryWrapper) {
        return getBaseDao().selectCount(queryWrapper);
    }

    @Override
    public List<T> selectList(Wrapper<T> queryWrapper) {
        return getBaseDao().selectList(queryWrapper);
    }

    @Override
    public PageResult<T> selectList(PageRequest<T> page, Wrapper<T> queryWrapper) {
        return getBaseDao().selectList(page, queryWrapper);
    }

    public int deleteJoin(Wrapper<T> wrapper) {
        return getBaseDao().deleteJoin(wrapper);
    }

    public int updateJoin(T entity, Wrapper<T> wrapper) {
        return getBaseDao().updateJoin(entity, wrapper);
    }

    public int updateJoinAndNull(T entity, Wrapper<T> wrapper) {
        return getBaseDao().updateJoinAndNull(entity, wrapper);
    }

    public Long selectJoinCount(Wrapper<T> wrapper) {
        return getBaseDao().selectJoinCount(wrapper);
    }

    public <DTO, P extends PageRequest<DTO>> PageResult<DTO> selectJoinPage(P page, Class<DTO> clazz, Wrapper<T> wrapper) {
        return getBaseDao().selectJoinPage(page, clazz, wrapper);
    }

}
